from odoo import fields, models, api


class FloatingCoefficient(models.Model):
    _name = 'floating.coefficient'
    _description = 'Floating Coefficient'
    _order = 'float asc'
    name = fields.Char(string='Name', compute='_compute_name', store=True, readonly=True)
    float = fields.Float(string='Float', default=10.0, required=True)

    @api.depends('name', 'float')
    def _compute_name(self):
        for rec in self:
            try:
                new_name = self.name.replace('%', '')
                new_name.strip()
                rec.float = float(new_name)
            except Exception as e:
                pass
            rec.name = str(rec.float) + '%'


class CrmQuotationLine(models.Model):
    _name = 'crm.quotation.line'
    _description = 'crm.quotation.line'
    crm_id = fields.Many2one('crm.lead', string='CRM ID', ondelete='cascade')
    floating_coefficient = fields.Many2one('floating.coefficient', string="Floating%", default=False, help="Float Adjustment Coefficient")
    qty = fields.Integer(string="MOQ(PCS)", default=1)
    lt = fields.Integer(string="LT", default=1)
    uom_char = fields.Selection([
        ('day', 'Days'),
        ('month', 'WDs'),
        ('week', 'Weeks'),
    ], string="UOM", default='day')
    m_uom_char = fields.Selection([
        ('day', 'Days'),
        ('month', 'WDs'),
        ('week', 'Weeks'),
    ], string="UOM", default='week')
    area = fields.Float(string="Area(M²)", store=True, digits=(16, 5), compute='_compute_area', compute_sudo=True)
    delivery_cost = fields.Monetary(string="Freight", default=0.0, currency_field='currency')
    unit_price = fields.Monetary(
        string="Unit Price", default=1.0, store=True, readonly=True, compute='_compute_price_and_amount',
        compute_sudo=True,
        help="((square_meter_price + delivery_cost) * (1 + commission)) * area / qty * (1 + floating)",
        currency_field='currency'
    )
    total_amount = fields.Monetary(
        string="TTL Amount", default=1.0, store=True, currency_field='currency',
        compute='_compute_price_and_amount',
        compute_sudo=True
    )
    production_cost = fields.Monetary(
        string="Process cost(CNY)", default=1.0, store=True,
        currency_field='currency_cny',
        compute='_compute_production_cost',
        compute_sudo=True
    )
    nre = fields.Float(string="NRE", default=0)
    mov = fields.Float(string="MOV", default=0)
    currency = fields.Many2one('res.currency', string="Currency", related='crm_id.customer_currency')
    currency_usd = fields.Many2one('res.currency', string="Currency", default=lambda self: self.env.ref('base.USD').id)
    currency_cny = fields.Many2one('res.currency', string="Currency", default=lambda self: self.env.ref('base.CNY').id)
    square_meter_price = fields.Monetary(string="Price/M²(USD)", default=1.0, currency_field='currency_usd', store=True)
    target_price = fields.Monetary(string="Target Price", default=0, currency_field='currency')
    t_square_meter_price = fields.Monetary(
        string="Target Price/M²", default=0, store=True, compute_sudo=True,
        currency_field='currency_usd',
        compute='_compute_price_and_amount'
    )
    t_production_cost = fields.Monetary(
        string="Target Process cost(CNY)", default=0, store=True, currency_field='currency_cny',
        compute='_compute_price_and_amount',
        compute_sudo=True
    )
    material_lt = fields.Integer(string="M.LT", default=1)
    tooling_cost = fields.Float(string="Tooling Cost", digits=(16, 2), default=0, compute='_compute_tooling_cost', store=True, readonly=False)
    ttl_freight = fields.Monetary(string="Total Freight", compute='_compute_freight_and_amount', store=True, currency_field='currency')
    print = fields.Boolean(string="Print", default=True, help="Whether to print this quotation line")

    @api.model
    def default_get(self, fields_list):
        res = super(CrmQuotationLine, self).default_get(fields_list)
        active_id = self._context.get('default_crm_id')
        if active_id:
            order = self.env['crm.lead'].browse(active_id)
            if order.quotation_lines:
                last_line = order.quotation_lines[0]
                copy_vals = last_line.copy_data()[0]
                fields_to_copy = [
                    'm_uom_char', 'square_meter_price', 'target_price', 'delivery_cost', 'uom_char', 'production_cost', 'lt', 'material_lt', 'nre', 'mov', 'floating_coefficient'
                ]
                for field in fields_to_copy:
                    if field in res and field in copy_vals:
                        res[field] = copy_vals[field]
        return res

    @api.depends('crm_id.tooling_cost')
    def _compute_tooling_cost(self):
        for rec in self:
            if not rec.crm_id.tooling_cost:
                rec.tooling_cost = 0
            else:
                pass

    @api.depends('crm_id.ttl_freight', 'delivery_cost', 'area')
    def _compute_freight_and_amount(self):
        for crm in self:
            if crm.crm_id.ttl_freight:
                crm.ttl_freight = crm.delivery_cost * crm.area
            else:
                crm.ttl_freight = 0

    @api.depends('crm_id', 'crm_id.panel_size_long', 'crm_id.panel_size_width', 'crm_id.pcs_in_panel', 'qty')
    @api.onchange('crm_id', 'crm_id.panel_size_long', 'crm_id.panel_size_width', 'crm_id.pcs_in_panel', 'qty')
    def _compute_area(self):
        for rec in self:
            rec.area = rec.crm_id.panel_size_width * rec.crm_id.panel_size_long * rec.qty / rec.crm_id.pcs_in_panel / 1000000

    @api.depends('square_meter_price', 'qty', 'delivery_cost', 'area', 'floating_coefficient', 'target_price', 'crm_id.commission', 'crm_id.materials_cost',
                 'crm_id.cost_of_surface', 'crm_id.other_expenses_i')
    @api.onchange('square_meter_price', 'qty', 'delivery_cost', 'area', 'floating_coefficient', 'target_price', 'crm_id.commission', 'crm_id.materials_cost',
                  'crm_id.cost_of_surface', 'crm_id.other_expenses_i')
    def _compute_price_and_amount(self):
        for rec in self:
            floating = rec.floating_coefficient.float / 100 if rec.floating_coefficient else 0
            rate = self.env['res.currency']._get_conversion_rate(self.env.ref('base.USD'), rec.currency, date=rec.create_date)
            rate_cny = self.env['res.currency']._get_conversion_rate(self.env.ref('base.USD'), self.env.ref('base.CNY'), date=rec.create_date)
            unit_price = ((rec.square_meter_price * rate * (1 + floating) + rec.delivery_cost) * (1 + rec.crm_id.commission)) * rec.area / rec.qty
            rec.total_amount = unit_price * rec.qty
            rec.unit_price = unit_price
            if rec.target_price and rec.area:
                minuend = rec.crm_id.materials_cost + rec.crm_id.cost_of_surface + rec.crm_id.other_expenses_i
                rec.t_square_meter_price = (rec.target_price * rec.qty / rec.area / (1 + rec.crm_id.commission) - rec.delivery_cost) / rate / (1 + floating)
                rec.t_production_cost = rec.t_square_meter_price * rate_cny * (1 + floating) - minuend
            else:
                rec.t_square_meter_price = 0
                rec.t_production_cost = 0

    @api.depends('square_meter_price', 'crm_id.materials_cost', 'crm_id.cost_of_surface', 'crm_id.other_expenses_i', 'floating_coefficient')
    @api.onchange('square_meter_price', 'crm_id.materials_cost', 'crm_id.cost_of_surface', 'crm_id.other_expenses_i', 'floating_coefficient')
    def _compute_production_cost(self):
        for rec in self:
            floating = rec.floating_coefficient.float / 100 if rec.floating_coefficient else 0
            rate = self.env['res.currency']._get_conversion_rate(self.env.ref('base.USD'), self.env.ref('base.CNY'), date=rec.create_date)
            minuend = rec.crm_id.materials_cost + rec.crm_id.cost_of_surface + rec.crm_id.other_expenses_i
            rec.production_cost = (rec.square_meter_price * rate * (1 + floating) * 1.13 - minuend) / 1.13
